package com.syyo.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syyo.common.enums.ResultEnum;
import com.syyo.common.exception.SysException;
import com.syyo.common.utils.MyHttpUtils;
import com.syyo.common.vo.MemberVo;
import com.syyo.gulimall.member.domain.entity.MemberEntity;
import com.syyo.gulimall.member.domain.entity.MemberLevelEntity;
import com.syyo.gulimall.member.domain.req.MemberReq;
import com.syyo.gulimall.member.domain.vo.MemberLoginVo;
import com.syyo.gulimall.member.domain.vo.MemberRegistVo;
import com.syyo.gulimall.member.domain.vo.SocialUser;
import com.syyo.gulimall.member.enums.MemberResultEnum;
import com.syyo.gulimall.member.mapper.MemberLevelMapper;
import com.syyo.gulimall.member.mapper.MemberMapper;
import com.syyo.gulimall.member.service.MemberService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;


/**
 * 会员
 *
 * @author syyo
 * @email syyo@gmail.com
 * @date 2021-01-20 09:52:10
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberEntity> implements MemberService {

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private MemberLevelMapper memberLevelMapper;


    /**
     * 新增
     */
    @Override
    @Transactional
    public int add(MemberReq req) {
        MemberEntity entity = new MemberEntity();
        // 添加创建时间和更新时间
        BeanUtils.copyProperties(req, entity);
        int insert = memberMapper.insert(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10001.getCode(), ResultEnum.E_10001.getMessage());
        }
        return insert;
    }

    /**
     * 删除
     */
    @Override
    @Transactional
    public int del(Integer id) {
        int insert = memberMapper.deleteById(id);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10002.getCode(), ResultEnum.E_10002.getMessage());
        }
        return insert;
    }

    /**
     * 编辑
     */
    @Override
    @Transactional
    public int edit(MemberReq req) {
        MemberEntity entity = new MemberEntity();
        // 添加更新时间
        BeanUtils.copyProperties(req, entity);
        int insert = memberMapper.updateById(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10003.getCode(), ResultEnum.E_10003.getMessage());
        }
        return insert;
    }

    /**
     * 详情
     */
    @Override
    public MemberEntity findOne(Integer id) {
        return memberMapper.selectById(id);
    }

    /**
     * 列表
     */
    @Override
    public IPage<MemberEntity> findPage(Integer pageNum, Integer pageSize, MemberReq req) {
        Page<MemberEntity> teacherPage = new Page<MemberEntity>(pageNum, pageSize);
        QueryWrapper<MemberEntity> wrapper = new QueryWrapper<>();
        return memberMapper.selectPage(teacherPage, wrapper);
    }

    /**
     * 列表
     */
    @Override
    public List<MemberEntity> findAll(MemberReq req) {
        QueryWrapper<MemberEntity> wrapper = new QueryWrapper<>();
        return memberMapper.selectList(wrapper);
    }

    @Override
    public int regist(MemberRegistVo req) {
        // 校验手机号和用户名是否重复
        checkUsernameUnique(req.getUserName());
        checkPhoneUnique(req.getPhone());

        MemberEntity entity = new MemberEntity();
        // 获取默认等级
        MemberLevelEntity levelEntity = memberLevelMapper.getDefaultLevel();
        entity.setLevelId(levelEntity.getId());

        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

        String encode = passwordEncoder.encode(req.getPassWord());

        //
        entity.setUsername(req.getUserName());

        entity.setPassword(encode);
        entity.setMobile(req.getPhone());
        entity.setNickname(req.getUserName());
        int insert = memberMapper.insert(entity);
        if (insert != 1) {
            throw new SysException(ResultEnum.E_10001.getCode(), ResultEnum.E_10001.getMessage());
        }
        return insert;
    }

    @Override
    public MemberEntity login(MemberLoginVo req) {
        // 查询密码
        MemberEntity memberEntity = memberMapper.selectOne(new QueryWrapper<MemberEntity>()
                .eq("username", req.getLoginAcct())
                .or()
                .eq("mobile", req.getLoginAcct()));
        if (memberEntity == null) {
            // 登录失败
            throw new SysException(MemberResultEnum.E_20003.getCode(), MemberResultEnum.E_20003.getMessage());
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matches = passwordEncoder.matches(req.getPassWord(), memberEntity.getPassword());
        if (matches) {
            // 成功
            return memberEntity;
        } else {
            // 密码错误
            throw new SysException(MemberResultEnum.E_20003.getCode(), MemberResultEnum.E_20003.getMessage());
        }
    }

    /**
     * 社交账号登录
     *
     * @param req
     * @return
     */
    @Override
    public MemberVo authlogin(SocialUser req) {
        String uid = req.getUid();
        MemberVo memberVo = new MemberVo();
        MemberEntity memberEntity = memberMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid));
        if (memberEntity != null) {
            // 这个用户注册过，更新令牌
            MemberEntity entity = new MemberEntity();
            entity.setId(memberEntity.getId());
            entity.setAccessToken(req.getAccess_token());
            entity.setExpiresIn(req.getExpires_in());
            int insert = memberMapper.updateById(entity);
            if (insert != 1) {
                throw new SysException(ResultEnum.E_10003.getCode(), ResultEnum.E_10003.getMessage());
            }
            memberEntity.setAccessToken(req.getAccess_token());
            memberEntity.setExpiresIn(req.getExpires_in());
            BeanUtils.copyProperties(memberEntity, memberVo);
        } else {
            // 没有注册过，需要注册
            MemberEntity entity = new MemberEntity();
            try {
                String url = "https://api.weibo.com/2/users/show.json";
                HashMap<String, String> map = new HashMap<>();
                map.put("access_token", req.getAccess_token());
                map.put("uid", uid);
                String s = MyHttpUtils.get(url, map);
                JSONObject jsonObject = JSON.parseObject(s);
                String name = jsonObject.getString("name");
                String gender = jsonObject.getString("gender");
                // 这个用户注册过，更新令牌

                // 添加创建时间和更新时间
                entity.setSocialUid(req.getUid());
                entity.setAccessToken(req.getAccess_token());
                entity.setExpiresIn(req.getExpires_in());
                entity.setNickname(name);
                entity.setGender("m".equals(gender) ? 1 : 0);
            } catch (Exception e) {
            }

            int insert = memberMapper.insert(entity);
            BeanUtils.copyProperties(entity, memberVo);
        }

        return memberVo;
    }

    /**
     * 校验手机号重复
     */
    private void checkPhoneUnique(String phone) {
        Integer mobile = memberMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (mobile > 0) {
            throw new SysException(MemberResultEnum.E_20002.getCode(), MemberResultEnum.E_20002.getMessage());
        }

    }

    /**
     * 校验用户名重复
     */
    private void checkUsernameUnique(String userName) {
        Integer username = memberMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", userName));
        if (username > 0) {
            throw new SysException(MemberResultEnum.E_20001.getCode(), MemberResultEnum.E_20001.getMessage());
        }
    }

}